package helper;

import com.aliyun.opensearch.CloudsearchClient;
import com.aliyun.opensearch.CloudsearchDoc;
import com.aliyun.opensearch.CloudsearchSearch;
import com.aliyun.opensearch.object.KeyTypeEnum;
import com.google.gson.JsonObject;
import org.apache.commons.lang.StringUtils;
import play.Logger;
import play.mvc.Before;
import product.Product;
import product.ProductTypes;
import product.merchant.ProductSpecMerchant;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by buhaoba on 16/6/17.
 */
public class AliyunOpenSearch {


     public static String accesskey = GlobalConfig.ALI_SEARCH_ACCESSKEY;
     public static String secret = GlobalConfig.ALI_SEARCH_SECRET;
     public static String api_url = GlobalConfig.ALI_SEARCH_API;
     public static String appName = GlobalConfig.ALI_SEARCH_APP_NAME;
//     public static String tempName = GlobalConfig.ALI_SEARCH_TEMP;
     public static CloudsearchClient client;
     public static String ALI_SEARCH_TYPE_PRODUCT= "10000";
     public static String ALI_SEARCH_TYPE_OTHER= "90000";


    /**
     * 初始化 Client
     * @return
     */
    @Before
    public static CloudsearchClient init() {
         Map<String , Object> opts = new HashMap<>();
        try {
            client = new CloudsearchClient(accesskey , secret , api_url , opts , KeyTypeEnum.ALIYUN);
        } catch (UnknownHostException e) {
            Logger.info("初始化 Client 失败 : %s" , e.getMessage());
            e.printStackTrace();
        }
        return client;
    }

    /**
     * 上传产品到 阿里云 OpenSearch
     * @param productSpecMerchant 产品信息
     * Product 必须包含信息 :
     *                      id     标示
     *                      title  标题
     *                      desc   表述
     * Product 信息通过 JsonObject 转换成
     *                [{"cmd" , "ADD" , "fields" : {"id" , "10000产品Id" , "title" , "产品标题" , "desc" , "产品内容"}}]
     * @return doc.push 返回结果.  以 status 是否为 "OK" 作为判断
     */
    public static String uploadProduct (ProductSpecMerchant productSpecMerchant) {
        CloudsearchClient client = AliyunOpenSearch.init();
        CloudsearchDoc doc = new CloudsearchDoc(AliyunOpenSearch.appName, client);

        Logger.info("DOC : %s  | appName : %s" , doc , AliyunOpenSearch.appName);


        JsonObject json = new JsonObject();
        json.addProperty("cmd" , "ADD");

        JsonObject fieldsJson = new JsonObject();
        fieldsJson.addProperty("id" , productSpecMerchant.id.intValue());
        fieldsJson.addProperty("name" , productSpecMerchant.productSpec.product.name);
        fieldsJson.addProperty("desc" , productSpecMerchant.productSpec.product.content);
        fieldsJson.addProperty("img" , productSpecMerchant.productSpec.mainImage);
        fieldsJson.addProperty("spec" , productSpecMerchant.productSpec.spec);
        fieldsJson.addProperty("unit" , productSpecMerchant.productSpec.unit);
        fieldsJson.addProperty("merchantId" , productSpecMerchant.merchant.id);
        fieldsJson.addProperty("merchantname" , productSpecMerchant.merchant.name);

        List<ProductTypes> typesList = ProductTypes.findByProduct(productSpecMerchant.productSpec.product);
        String typeName = "";
        for(ProductTypes productTypes : typesList) {
            typeName += productTypes.type.name + "|";
//            if(productTypes.type.parentTypeId != null) {
//                ProductType productType = ProductType.findById(productTypes.type.parentTypeId);
//                if(productType != null && typeName.indexOf(productType.name) <= 0) {
//                    typeName += productType.name + "|";
//                }
//            }
        }


        fieldsJson.addProperty("typename" , typeName);
        fieldsJson.addProperty("price" , productSpecMerchant.merchantPrice);
        fieldsJson.addProperty("status" , productSpecMerchant.productStatus.toString());
        json.add("fields" , fieldsJson);
        try {
            String jsonString = "[" +json.toString() + "]";
            String docName = doc.push( jsonString ,  "main");
            Logger.info("文件内容提交成功 : %s" , docName);
            return docName;
        } catch (IOException e) {
            Logger.info("OpenSearch Error : %s"  , e.getMessage());
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 上传 内容到 阿里云 OpenSearch
     * @param date  要存入到 OpenSearch 的数据
     * 数据格式: {"id":"90000001" , "title" , "展示标题" , "desc" , "展示内容"}
     * 多条数据格式:
     *          {"id":"90000001" , "title" , "展示标题1" , "desc" , "展示内容1"} ,
     *          {"id":"90000002" , "title" , "展示标题2" , "desc" , "展示内容2"} ,
     *          {"id":"90000003" , "title" , "展示标题3" , "desc" , "展示内容3"}
     *  最后提交组合格式:
     *          [{"cmd" , "ADD" , "fields" : {"id" , "9000001" , "title" , "展示标题" , "desc" , "展示内容"}}]
     * @return doc.push 返回结果.  以 status 是否为 "OK" 作为判断
     */
    public static String uplpadToDoc(String date) {
        if(StringUtils.isBlank(date)) {
            return "";
        }
        CloudsearchDoc doc = new CloudsearchDoc(AliyunOpenSearch.appName, client);
        //开始时间
        JsonObject json = new JsonObject();
        json.addProperty("cmd" , "ADD");
        json.addProperty("fields" , date);
        try {
            return doc.push( "[" +json.toString() + "]" ,  "main");
        } catch (IOException e) {
            Logger.info("OpenSearch Error : %s"  , e.getMessage());
            e.printStackTrace();
            return "";
        }
    }



    /**
     * 在文档总 搜索 关键字
     * @param pageNo  当前分页页码
     * @param pageSize 每页显示数量
     * @param keyWord  要搜索的关键字
     * @throws Exception 搜索一场处理
     * @return 返回解析到的JSON 数据
     * {"status":"OK","request_id":"146638258617779943422628","result":{"searchtime":0.006818,"total":6,"num":6,"viewtotal":6,"items":[{"id":"3","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"2","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"1","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"0","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"4","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"11","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"}],"facet":[]},"errors":[{"code":2112,"message":"No index in query"}],"tracer":""}
     */
    public static String queryOpenSearch(String keyWord ,  Integer pageNo , Integer pageSize){
        Logger.info("LOG SEARCH  keyword : %s | pageNo : %s | pageSize : %s" , keyWord , pageNo , pageSize);
        CloudsearchSearch search = new CloudsearchSearch(AliyunOpenSearch.init());
        // 添加指定搜索的应用：
        search.addIndex(AliyunOpenSearch.appName);
        // 索引字段名称是您在您的数据结构中的“索引到”字段。
//            search.setQueryString("status:'UP'  AND default:'"+ keyWord.trim() +"'");
            search.setQueryString("status:'UP' AND reviewstatus:'NORMAL' AND deleted:'UN_DELETED' AND default:'"+ keyWord.trim() +"'");
//        search.setQueryString("status:'UP' AND merchantid: '" + merchantId + "'  AND default:'"+ keyWord.trim() +"'");
//        search.setQueryString("status:'UP' AND merchantid: '" + merchantId + "'  AND default:'"+ keyWord.trim() +"'");

        //参数一 要飘红的字段 、参数二 数据截取字数100、参数三 多余部分...显示、参数四飘红显示几段 、参数五六为html标签可以自定义
        search.addSummary("name", 30, "...", 1, "<font color='red'>", "</font>");
        search.addSummary("spec", 30, "...", 1, "<font color='red'>", "</font>");
        //分页查询
        search.setStartHit((pageNo-1) * pageSize > 0 ? (pageNo - 1) * pageSize : 0);
//        search.setStartHit(1);
        //每页显示10条
        search.setHits(pageSize);
        //指定搜索返回的格式为json
        search.setFormat("json");
        try {
            return search.search();
        } catch (IOException ioe) {
            Logger.info("Error :" + ioe.getMessage());
        }
        return null;
    }


    /**
     * 在文档总 搜索 关键字
     * @param pageNo  当前分页页码
     * @param pageSize 每页显示数量
     * @param keyWord  要搜索的关键字
     * @param orderByWord 排序的关键字
     * @param orderBy     排列顺序 正序+  倒序-
     * * @throws Exception 搜索一场处理
     * @return 返回解析到的JSON 数据
     * {"status":"OK","request_id":"146638258617779943422628","result":{"searchtime":0.006818,"total":6,"num":6,"viewtotal":6,"items":[{"id":"3","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"2","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"1","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"0","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"4","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"},{"id":"11","type":"0","source":"0","city":"","name":"","title":"你好 你好 你好 ","desc":"<font color='red'>你好</font> 我......","address":"","region_ids":"0","cbd_ids":"0","img":"","url":"","wap_url":"","coupon_starttime":"0","coupon_endtime":"0","origin_price":"0","activity_price":"0","sold_count":"0","item_count":"0","discount":"0","is_reserve_free":"0","modify_time":"0","cat_ids":"0","lat":"0","lng":"0","index_name":"ulmsale"}],"facet":[]},"errors":[{"code":2112,"message":"No index in query"}],"tracer":""}
     */
    public static String queryOpenSearch(String keyWord ,  Integer pageNo , Integer pageSize , String orderByWord , String orderBy) {
        Logger.info("LOG SEARCH  keyword : %s | pageNo : %s | pageSize : %s" , keyWord , pageNo , pageSize);
        CloudsearchSearch search = new CloudsearchSearch(AliyunOpenSearch.init());
        // 添加指定搜索的应用：
        search.addIndex(AliyunOpenSearch.appName);
        // 索引字段名称是您在您的数据结构中的“索引到”字段。
        search.setQueryString("   status:'UP' AND reviewstatus:'NORMAL' AND deleted:'UN_DELETED' AND  name:'"+ keyWord.trim() +"'");

        //参数一 要飘红的字段 、参数二 数据截取字数100、参数三 多余部分...显示、参数四飘红显示几段 、参数五六为html标签可以自定义
        search.addSummary("name", 30, "...", 1, "<font color='red'>", "</font>");
        search.addSummary("spec", 30, "...", 1, "<font color='red'>", "</font>");
        //分页查询
        search.setStartHit((pageNo-1) * pageSize > 0 ? (pageNo - 1) * pageSize : 0);
//        search.setStartHit(1);
        //每页显示10条
        search.setHits(pageSize);
        //指定搜索返回的格式为json
        search.setFormat("json");
        search.addSort(orderByWord , orderBy);
        try {
            return search.search();
        } catch (IOException e) {
            Logger.info("SearchError :" + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }


    public static String uploadProductByRiZhi(Product product) {
        CloudsearchClient client = AliyunOpenSearch.init();
        CloudsearchDoc doc = new CloudsearchDoc(AliyunOpenSearch.appName, client);


        Logger.info("DOC : %s  | appName : %s" , doc , AliyunOpenSearch.appName);

        List<ProductTypes> typesList = ProductTypes.findByProduct(product);
        String typeName = "";
        for(ProductTypes productTypes : typesList) {
            typeName += productTypes.type.name + "|";
        }
        JsonObject json = new JsonObject();
        json.addProperty("cmd" , "ADD");

        JsonObject fieldsJson = new JsonObject();
        fieldsJson.addProperty("id" , product.id.intValue());
        fieldsJson.addProperty("name" , product.name);
        fieldsJson.addProperty("desc" ,product.content);
        fieldsJson.addProperty("img" , product.mainImage);
        fieldsJson.addProperty("spec" , product.spec);
        fieldsJson.addProperty("unit" , product.unit);
        fieldsJson.addProperty("merchantId" , product.merchant.id);
        fieldsJson.addProperty("merchantname" , product.merchant.name);
        fieldsJson.addProperty("typename" , typeName);
        fieldsJson.addProperty("price" , product.merchantPrice);
        fieldsJson.addProperty("oldPrice" , product.oldPrice);
        fieldsJson.addProperty("status" , product.productStatus.toString());
        fieldsJson.addProperty("salesvolumes" ,  product.salesvolumes);
        fieldsJson.addProperty("reviewstatus" ,  product.reviewStatus.toString());
        Logger.info("product.deleted.toString()  : %s" ,product.deleted.toString().trim());
        fieldsJson.addProperty("deleted" ,  product.deleted.toString());
        fieldsJson.addProperty("weightvalue" ,  product.weightValue);
        json.add("fields" , fieldsJson);
        try {
            String jsonString = "[" +json.toString() + "]";
            String docName = doc.push( jsonString ,  "main");
            Logger.info("文件内容提交成功 : %s" , docName);
            return docName;
        } catch (IOException e) {
            Logger.info("OpenSearch Error : %s"  , e.getMessage());
            e.printStackTrace();
            return "";
        }
    }


    public static String uploadProductAddSalesvolumes(Product product) {
        CloudsearchClient client = AliyunOpenSearch.init();
        CloudsearchDoc doc = new CloudsearchDoc(AliyunOpenSearch.appName, client);


        Logger.info("DOC : %s  | appName : %s" , doc , AliyunOpenSearch.appName);

        List<ProductTypes> typesList = ProductTypes.findByProduct(product);
        String typeName = "";
        for(ProductTypes productTypes : typesList) {
            typeName += productTypes.type.name + "|";
        }
        JsonObject json = new JsonObject();
        json.addProperty("cmd" , "ADD");

        JsonObject fieldsJson = new JsonObject();
        fieldsJson.addProperty("id" , product.id.intValue());
        fieldsJson.addProperty("name" , product.name);
        fieldsJson.addProperty("desc" ,product.content);
        fieldsJson.addProperty("img" , product.mainImage);
        fieldsJson.addProperty("spec" , product.spec);
        fieldsJson.addProperty("unit" , product.unit);
        fieldsJson.addProperty("merchantId" , product.merchant.id);
        Logger.info("merchantname====",product.merchant.name);
        fieldsJson.addProperty("merchantname" , product.merchant.name);
        fieldsJson.addProperty("typename" , typeName);
        fieldsJson.addProperty("price" , product.merchantPrice);
        fieldsJson.addProperty("oldPrice" , product.oldPrice);
        fieldsJson.addProperty("status" , product.productStatus.toString());
        fieldsJson.addProperty("salesvolumes" , product.salesvolumes);
        fieldsJson.addProperty("reviewstatus" ,  product.reviewStatus.toString());
        json.add("fields" , fieldsJson);
        try {
            String jsonString = "[" +json.toString() + "]";
            String docName = doc.push( jsonString ,  "main");
            Logger.info("文件内容提交成功 : %s" , docName);
            return docName;
        } catch (IOException e) {
            Logger.info("OpenSearch Error : %s"  , e.getMessage());
            e.printStackTrace();
            return "";
        }
    }
}
